import React, { PureComponent } from 'react';
import { connect } from 'dva';
import "./form.less"
import "../../Common.less"
import {cloneDeep} from "lodash"
import { Table, Input, Tabs, Icon, Form, Radio, notification, Modal } from 'antd';
const { TabPane } = Tabs;
const EditableContext = React.createContext();

const EditableRow = ({ form, index, ...props }) => (
    <EditableContext.Provider value={form}>
        <tr {...props} />
    </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends PureComponent {
    state = {
        editing: false,
    };

    toggleEdit = () => {
        const editing = !this.state.editing;
        this.setState({ editing }, () => {
            if (editing) {
                this.input.focus();
            }
        });
    };

    save = e => {
        const { record, handleSave } = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            handleSave({ ...record, ...values });
        });
    };

    renderCell = form => {
        this.form = form;
        const { children, dataIndex, record, title } = this.props;
        const { editing } = this.state;
        return editing ? (
            <Form.Item style={{ margin: 0 }}>
                {form.getFieldDecorator(dataIndex, {
                    rules: [
                        {
                            required: true,
                            message: `请填写属性`,
                        },
                    ],
                    initialValue: record[dataIndex],
                })(<Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save} />)}
            </Form.Item>
        ) : (
                <div
                    className="editable-cell-value-wrap"
                    onClick={this.toggleEdit}
                >
                    {children}
                </div>
            );
    };

    render() {
        const {
            editable,
            dataIndex,
            title,
            record,
            index,
            handleSave,
            children,
            ...restProps

        } = this.props;
        return (
            <td {...restProps}>
                {editable ? (
                    <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
                ) : (
                        children
                    )}
            </td>
        );
    }
}
class CusTable extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            cindex1: 0,
            cindex2: 0,
            columns: [],
            data: [],
            count: 2,
        };
        this.onConfirm = this.onConfirm.bind(this)
        this.tabCgange = this.tabCgange.bind(this)
        this.switchStruc = this.switchStruc.bind(this)
        this.formatData = this.formatData.bind(this)
        this.massFormat = this.massFormat.bind(this)
        this.handleModeChange = this.handleModeChange.bind(this)
        this.getDictName = this.getDictName.bind(this)
        this.init = this.init.bind(this)
        this.dragenter = this.dragenter.bind(this)
        this.drag = this.drag.bind(this)
        this.drop = this.drop.bind(this)
        this.dragover = this.dragover.bind(this)
        this.dragend = this.dragend.bind(this)
        this.preview = this.preview.bind(this)
    }
    dragenter(e) {
        e.persist();
        // console.log("dragenter",record)
        if (!e.target.classList.contains("corRed")) {
            e.target.classList.add("corRed")
        }

        return true;
    }
    drag(e, record) {
        e.persist();
        e.dataTransfer.effectAllowed = "move";
        e.dataTransfer.setData("text", e.target.dataset.item);
        return true
    }
    drop(e, record) {
        e.persist();
        let { data } = this.state;
        let datac = JSON.parse(e.dataTransfer.getData("text"));
        let obj = {
            index: record.index,
            id: record.id,
            code: record.code,
            spanName: record.spanName
        }
        for (const key in datac) {
            if (Object.hasOwnProperty.call(datac, key)) {
                let item = datac[key];
                if (!['index', 'id', 'code', 'spanName'].includes(key)) {
                    obj[key] = item
                }
            }
        }
        data.splice(record.index - 1, 1, obj)
        this.setState({
            data: [...data]
        })
        if (e.target.classList.contains("corRed")) {
            e.target.classList.remove("corRed")
        }
        return false;
    }
    dragend(e) {
        e.persist();
        e.dataTransfer.clearData("text");

        return false
    }
    dragleave(e) {
        e.persist();
        if (e.target.classList.contains("corRed")) {
            e.target.classList.remove("corRed")
        }

        return true
        // console.log("dragleave",e)
    }
    dragover(e) {
        e.persist();
        e.dataTransfer.effectAllowed = "move";
        e.preventDefault();
        return true;

    }
    onConfirm(params) {
        return new Promise((resolve, reject) => {
            let { massFormatData } = this.state;
            const { extra } = this.props;
            let arr = [];
            const len = massFormatData.length;
            for (let i = 0; i < len; i++) {
                let item = massFormatData[i];
                const len2 = item.length;
                for (let k = 0; k < len2; k++) {
                    let item2 = item[k];
                    const len3 = item2.datac.length;
                    for (let j = 0; j < len3; j++) {
                        let arr3 = []
                        let item3 = item2.datac[j];
                        for (const key in item3) {
                            if (Object.hasOwnProperty.call(item3, key)) {
                                if (key.includes('value')) {
                                    const cid = key.split('value_')[1];
                                    if (!item3[key]) {
                                        if (params.onError) {
                                            params.onError("请将参数填写完整")
                                        }
                                        notification.warn({ message: "请将参数填写完整!" })
                                        reject("请将参数填写完整")
                                        return;
                                    }
                                    arr3.push({
                                        id: item3['ins_' + cid],
                                        value: item3[key],
                                    })
                                }
                            }
                        }
                        arr.push(arr3)
                    }
                }

            }
            this.props.addBottomProperty({ data: arr, type: extra.type }, res => {
                if (params.onSuccess) {
                    params.onSuccess()
                }
                resolve(res)
            }, err => {
                if (params.onError) {
                    params.onError(err)
                }
                reject()
            })
        })
    }
    async massFormat() {
        return new Promise(async (resolve, reject) => {
            const {designedStructuresCopy}=this.state;
            const designedStructuresCopy2 = designedStructuresCopy && designedStructuresCopy.length ?designedStructuresCopy : cloneDeep(this.props.extra.designedStructures);
            const len = designedStructuresCopy2.length;
            let arr = []
            if (len && len - 0 > 0) {
                for (let i = 0; i < len; i++) {
                    let item = designedStructuresCopy2[i];
                    const len2 = item.components.length;
                    let arr2 = []
                    for (let j = 0; j < len2; j++) {
                        const { columnsc, datac } = this.formatData(i, j)
                        arr2.push({
                            columnsc,
                            datac
                        })
                    }
                    arr.push(arr2)
                }
                await this.setState({
                    massFormatData: arr
                })

                resolve(arr)
            } else {
                reject()
            }
        })

    }
    async componentDidMount() {
        if (this.props.onLoaded) {
            this.props.onLoaded(this);
        }
        this.init()
    }
    async init() {
        const { dictlist } = this.props;
        await this.setState({
            unitList: dictlist.filter(item => item.dictType == "unit"),
        })
        await this.massFormat()
        this.switchStruc(0, 0)
    }
    handleSave = row => {
        const { data, cindex1, cindex2, massFormatData } = this.state;
        const newData = [...data];
        const index = newData.findIndex(item => row.id === item.id);
        const item = newData[index];
        const { datac } = massFormatData[cindex1][cindex2]
        newData.splice(index, 1, {
            ...item,
            ...row,
        });
        datac.splice(index, 1, {
            ...item,
            ...row,
        });
        this.setState({ data: newData, massFormatData });
    }
    getDictName(list, attrEnName) {
        let obj = list.find(item => item.id == attrEnName);

        return obj ? obj.dictLabel : ""
    }
    formatData(index, index2) {
        const { extra } = this.props;
        const { unitList,designedStructuresCopy} = this.state

        const designedStructuresCopy2 = designedStructuresCopy && designedStructuresCopy.length ? designedStructuresCopy : cloneDeep(this.props.extra.designedStructures);
        const { dataList, titles } = designedStructuresCopy2[index].components[index2];
        let arr = extra.type == "bottom" ? [{
            title: '序号',
            dataIndex: 'index',
            key: 'index',
         
        }, {
            title: '桩号',
            dataIndex: 'code',
            key: 'code',
           
        }, {
            title: '墩号',
            dataIndex: 'spanName',
            key: 'spanName',
         
        }] : [{
            title: '序号',
            dataIndex: 'index',
            key: 'index',
           
        }, {
            title: '联号',
            dataIndex: 'spanName',
            key: 'spanName',
         
            render: (text, record) => text + "(" + record['express'] + ")"
        }, {
            title: '起止桩号',
            dataIndex: 'code',
            key: 'code',
       
        }], arr2 = [];
        if (titles && titles.length && dataList && dataList.length) {
            const len = titles.length;
            const len2 = dataList.length;
            for (let i = 0; i < len; i++) {
                let item = titles[i];
                arr.push(...[{
                    title: (text, record) => <span title={item.name}>{item.name.replace(/^([^\,]*).*$/, function ($all, $1) { return $1 })}({this.getDictName(unitList, item.unit)})</span>,
                    dataIndex: 'value_' + item.propertyId + "_" + index + "_" + index2,
                    key: 'value_' + item.propertyId + "_" + index + "_" + index2,
                    editable: true,
                    ellipsis: true,
                    render: text => <span>{text}&nbsp;<Icon type="edit" /></span>
                }])
            }
            arr.push({
                title: "操作",
                dataIndex: "operate",
                key: "operate",
                render: (text, record) => <div data-item={JSON.stringify(record)} onDragStart={e => this.drag(e, record)} onDragEnd={e => this.dragend(e, record)} onDragLeave={e => this.dragleave(e, record)} onDrop={e => this.drop(e, record)} onDragOver={e => this.dragover(e, record)} onDragEnter={e => this.dragenter(e, record)} draggable >复制&nbsp;<Icon type="copy" /></div>
            })
            for (let i = 0; i < len2; i++) {
                let item = dataList[i];
                let obj = {
                    index: i + 1,
                    id: item.id,
                    code: item.code,
                    [extra.type == "bottom" ? "spanName" : "spanName"]: item[extra.type == "bottom" ? "spanName" : "spanName"],
                    express: item['express'],

                }
                const len3=item.properties.length
                for (let j = 0; j < len3; j++) {
                    let item2 = item.properties[j];
                    Object.assign(obj, {
                        ['value_' + item2.propertyId + "_" + index + "_" + index2]: item2.value,
                        ['ins_' + item2.propertyId + "_" + index + "_" + index2]: item2.id
                    })

                }
                arr2.push(obj)


            }
            const columns = arr.map(col => {
                if (!col.editable) {
                    return col;
                }
                return {
                    ...col,
                    onCell: record => ({
                        record,
                        editable: col.editable,
                        dataIndex: col.dataIndex,
                        title: col.title,
                        id: col.id,
                        handleSave: this.handleSave,
                    }),
                };
            });
            this.setState({
                designedStructuresCopy:designedStructuresCopy2
            })
            return {
                columnsc: columns, datac: arr2
            }
        }

    }
    async switchStruc(index, index2, res) {
        const { columnsc, datac } = res || this.state.massFormatData[index][index2]

        this.setState({
            columns: columnsc,
            data: datac
        })

    }
    async tabCgange(e) {
        const index = (e + '').replace(/t|s/g, '')
        await this.setState({
            cindex2: index
        })
        const { cindex1, cindex2 } = this.state;
        this.switchStruc(cindex1, cindex2)
    }
    preview(e, url) {
        e.preventDefault()
        e.stopPropagation()
        if (url) {
            Modal.info({
                title: "构件预览",
                centered: true,
                content: <div><img src={url} alt="" /></div>,
                footer: null
            })
        }
        console.log(e, url)
    }
    async handleModeChange(e) {
        const list = this.props.extra.designedStructures
        const value = e.target.value;
        const index = list.findIndex(item => item.definitionNameZh == value)
        const { columnsc, datac } = this.state.massFormatData[index][0]
        this.setState({
            cindex1: index,
            cindex2: 0,
            columns: columnsc,
            data: datac
        })
    }
    render() {
        const { extra } = this.props;
        const { massFormatData, cindex1, cindex2, data } = this.state;
        const components = {
            body: {
                row: EditableFormRow,
                cell: EditableCell,
            },
        };
        return (
            <div>
                <Radio.Group onChange={this.handleModeChange} value={extra.designedStructures && extra.designedStructures.length ? extra.designedStructures[cindex1].definitionNameZh : ''} style={{ marginBottom: 8 }}>
                    {
                        extra.designedStructures && extra.designedStructures.length ? extra.designedStructures.map((item, index) => {
                            return <Radio.Button key={'t' + index} value={item.definitionNameZh}>{item.definitionNameZh}&nbsp;<Icon onClick={e => this.preview(e, item.imgPath)} style={{ marginLeft: "5px" }} type="eye" /></Radio.Button>
                        }) : undefined
                    }

                </Radio.Group>
                {
                    extra.designedStructures ? <Tabs tabBarStyle={{ width: "100px" }} tabPosition="left" size="small" defaultActiveKey="t0" onChange={this.tabCgange}>
                        {
                            extra.designedStructures[cindex1].components && extra.designedStructures[cindex1].components.length ? extra.designedStructures[cindex1].components.map((i, r) => {
                                return <TabPane tab={i.instanceComponentName + (i.number - 1 > 0 ? i.number : '')} key={'t' + r}>
                                    <div style={{ height: "350px" }}>
                                        <Table
                                            className="editTable"
                                            style={{ margin: "10px 0 10px 10px", height: "100%" }}
                                            rowKey={record => record.id + r + i.instanceComponentName + cindex1 + cindex2}
                                            components={components}
                                            rowClassName={() => 'editable-row'}
                                            bordered
                                            size="small"
                                            pagination={false}
                                            scroll={{ y: 300 }}
                                            dataSource={data}

                                            columns={massFormatData ? massFormatData[cindex1][cindex2].columnsc : []}
                                        />
                                    </div>
                                </TabPane>
                            }) : undefined
                        }

                    </Tabs>
                        : undefined}
            </div>
        );
    }
}
export default connect(
    ({ dict: { dictlist } }) => ({
        dictlist
    }),
    dispatch => ({
        addBottomProperty: (values, onSuccess, onError) => dispatch({
            type: 'structure/addBottomProperty',
            payload: {
                values, onSuccess, onError
            }
        }),
    })
)(Form.create('cusTable', {

})(CusTable));